package com.meida.module.bus.provider.api.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.utils.DateUtils;
import com.meida.module.bus.client.entity.*;
import com.meida.module.bus.client.entity.srmapi.basedata.SrmService;
import com.meida.module.bus.client.entity.srmapi.basedata.SrmUnit;
import com.meida.module.bus.client.entity.srmapi.basedata.SrmVendor;
import com.meida.module.bus.client.entity.srmapi.srmtopms.*;
import com.meida.module.bus.provider.api.util.ApiConstants;
import com.meida.module.bus.provider.api.util.PmsApiUtil;
import com.meida.module.bus.provider.api.util.PmsToolUtil;
import com.meida.module.bus.provider.mapper.BusMaterialComMapper;
import com.meida.module.bus.provider.service.*;
import com.meida.module.bus.provider.service.srmservice.SrmVendorService;
import com.meida.module.system.client.entity.SysDictData;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Base64Utils;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RefreshScope
@Transactional(rollbackFor = Exception.class)
public class SyncSrmSubService {
    @Autowired
    private BusPurchaseDetailsService busPurchaseDetailsService;
    @Autowired
    private BusMaterialPlan100Service busMaterialPlan100Service;
    @Autowired
    private BusMaterialPackage100Service package100Service;
    @Autowired
    private BusMaterialPackage200Service package200Service;
    @Autowired
    private BusSupplierService busSupplierService;
    @Autowired
    private BusMaterialSrmService busMaterialSrmService;
    @Autowired
    private BusMaterialSrmSubService srmSubService;
    @Autowired
    private BusPackageSrmService busPackageSrmService;
    @Autowired
    private SrmVendorService srmVendorService;
    @Autowired
    private BusProjectSupplierService projectSupplierService;
    @Autowired
    private PmsApiUtil pmsApiUtil;
    @Autowired
    private BusProjectPackSyncSrmService syncPackSrmService;
    @Resource
    private BusMaterialComMapper busMaterialComMapper;
    @Autowired
    private BusMaterialService busMaterialService;
    @Autowired
    private BusProjectFileService busProjectFileService;

    @Value("${file.url}")
    public String filePath;

    /**
     * 组装SRM01请求数据
     *
     * @param busPurchase
     * @param userName
     * @return
     */
    public SrmPms01Req getSrmPms01Req(BusPurchase busPurchase, String userName) throws Exception {
        SrmPms01Req srmPms01Req = new SrmPms01Req();
        BusProject busProject = pmsApiUtil.getProjectInfo(busPurchase.getDetails().get(0).getProjectId());

//        List<Long> chkLikst = Lists.newArrayList();
//        busPurchase.getDetails().stream().forEach(detailObj -> {
//            Object planData = pmsApiUtil.getMaterialPlanDataObj(detailObj.getPurchaseDetailsId(), busProject.getProjectId(), detailObj);
//
//        });
        //设置附件组ID值
        String fileGroupId = busProjectFileService.getFileGroupIdByPurchaseId(busPurchase.getPurchaseId());
        srmPms01Req.setFileGroupId(getAttributeValue(fileGroupId));
        // PMS材料申请计划ID
        srmPms01Req.setPurchaseId(busPurchase.getPurchaseId());
        // PMS材料申请计划编码
        srmPms01Req.setPurchaseNo(busPurchase.getPurchaseNo());
        // 单据类型_构建数据字典
        SysDictData sysDictData = pmsApiUtil.getSysDictData("docTypes", null, busPurchase.getDetails().get(0).getDocumentType());
        srmPms01Req.setDocumentType(sysDictData.getDicDataValue());
        // 项目编码
        srmPms01Req.setProjectNo(busProject.getProjectCode());
        // 项目名称
        srmPms01Req.setProjectName(busProject.getProjectName());
        // 公司编码
        srmPms01Req.setCompanyCode(ApiConstants.COMPANY_CODE);
        // 公司名称
        srmPms01Req.setCompanyName(ApiConstants.COMPANY_NM);
//        SrmProjectinfo projectinfo = (null != busPurchase.getProjectId() && 0L != busPurchase.getProjectId()) ? pmsApiUtil.getProjectInfoFromSrm(busPurchase.getProjectId()) : new SrmProjectinfo();
        // 采购组编码
        srmPms01Req.setPurchasingGroupCode(busProject.getGoodsPurGroupCode());
        // 采购组名称
        srmPms01Req.setPurchasingGroupName(busProject.getGoodsPurGroupName());
        // 申请人名称
        srmPms01Req.setProposer(userName);
        // 申请日期
        srmPms01Req.setApplyTime(DateUtil.parseDateTime(DateUtil.now()).getTime());
        // detail header
        Object planDataHeader = pmsApiUtil.getMaterialPlanDataObj(busPurchase.getDetails().get(0).getPurchaseDetailsId(), busProject.getProjectId(), busPurchase.getDetails().get(0));
        // 专业包代码
        srmPms01Req.setMajorCode(PmsToolUtil.getStrValue(planDataHeader, ApiConstants.INVOKE_GET_MAJORCODE));
        // 专业包名称
        srmPms01Req.setMajorName(PmsToolUtil.getStrValue(planDataHeader, ApiConstants.INVOKE_GET_MAJORNAME));
        // 工程包代码
        srmPms01Req.setPackageNo(PmsToolUtil.getStrValue(planDataHeader, ApiConstants.INVOKE_GET_PACKAGENO));
        // 工程包名称
        srmPms01Req.setPackageName(PmsToolUtil.getStrValue(planDataHeader, ApiConstants.INVOKE_GET_PACKAGENAME));

        List<SrmPms01ReqDetail> reqDetails = Lists.newArrayList();
        busPurchase.getDetails().stream().forEach(detailObj -> {
            StaticLog.debug("材料申请明细日志：" + detailObj.toString());
            Object planData = pmsApiUtil.getMaterialPlanDataObj(detailObj.getPurchaseDetailsId(), busProject.getProjectId(), detailObj);
//            BusSupplier busSupplier = pmsApiUtil.getBusSupplier(detailObj.getVendorId(), null);
            BusSupplier busSupplier = pmsApiUtil.getBusSupplier(detailObj.getVendorName());
            SrmPms01ReqDetail srmPms01ReqDetail = new SrmPms01ReqDetail();
            // PMS材料申请计划明细ID
            srmPms01ReqDetail.setPurchaseDetailsId(detailObj.getPurchaseDetailsId());
            // WBS号
            srmPms01ReqDetail.setWbsNo(PmsToolUtil.getStrValue(planData, ApiConstants.INVOKE_GET_MATERIALWBSCODE));
            // 物料编码
            srmPms01ReqDetail.setMaterialCode(PmsToolUtil.getStrValue(planData, ApiConstants.INVOKE_GET_MATERIALCODE));
            // 物料名称
            srmPms01ReqDetail.setMaterialName(PmsToolUtil.getStrValue(planData, ApiConstants.INVOKE_GET_MATERIALNAME));
            // 工厂编码
            srmPms01ReqDetail.setPlantCode(ApiConstants.COMPANY_CODE);
            // 计划数量
            BigDecimal planQty = PmsToolUtil.getBigDecimalValue(planData, ApiConstants.INVOKE_GET_PLANPURCHASECOUNT);
            planQty.setScale(3, BigDecimal.ROUND_HALF_DOWN);
            srmPms01ReqDetail.setPlanQty(String.valueOf(planQty));
            // 采购数量
            BigDecimal needQty = detailObj.getPurchaseNum();
            needQty.setScale(3, BigDecimal.ROUND_HALF_DOWN);
            srmPms01ReqDetail.setNeedQty(String.valueOf(needQty));
            // 单位名称
            srmPms01ReqDetail.setUnitCode(detailObj.getUnitCode());
            srmPms01ReqDetail.setUnitName(detailObj.getUnitName());
//            srmPms01ReqDetail.setUnitCode(pmsApiUtil.getUnitCode(PmsToolUtil.getStrValue(planData, ApiConstants.INVOKE_GET_MEASUREMENTUNIT)));
//            srmPms01ReqDetail.setUnitName(PmsToolUtil.getStrValue(planData, ApiConstants.INVOKE_GET_MEASUREMENTUNIT));
            // 需求时间
            String receivedDate = detailObj.getReceivedDate();
            if(StrUtil.isNotEmpty(receivedDate)) {
                if(receivedDate.contains("/")) {
                    receivedDate = receivedDate.replaceAll("/", "-");
                }
            }
            srmPms01ReqDetail.setNeedTime(DateUtil.parseDate(receivedDate).getTime());

            // 班组编码
            srmPms01ReqDetail.setVendorCode(busSupplier.getSupplierCode());
            // 班组
            srmPms01ReqDetail.setVendorName(busSupplier.getSupplierName());
            // 品牌
            // srmPms01ReqDetail.setBrand(PmsToolUtil.getStrValue(planData, ApiConstants.INVOKE_GET_BRANDNAME));
            srmPms01ReqDetail.setBrand(detailObj.getBrandName());
            // 使用区域，部位
            srmPms01ReqDetail.setUseArea(PmsToolUtil.getStrValue(planData, ApiConstants.INVOKE_GET_MATERIALAREA) + PmsToolUtil.getStrValue(planData, ApiConstants.INVOKE_GET_MATERIALUSE));
            // 备注
            // srmPms01ReqDetail.setRemark(PmsToolUtil.getStrValue(planData, ApiConstants.INVOKE_GET_MATERIASPECS));
            srmPms01ReqDetail.setRemark(getAttributeValue(detailObj.getTechnicalData()) + getAttributeValue(detailObj.getRemark()));
            reqDetails.add(srmPms01ReqDetail);
        });
        srmPms01Req.setDetails(reqDetails);
        return srmPms01Req;
    }

    /**
     * 获取属性值
     * @param val
     * @return
     */
    public String getAttributeValue(String val){
        return StringUtils.isNotBlank(val)?val:"";
    }

    /**
     * 组装SRM02请求数据
     */
    public List<SrmPms02Req> getSrmPms02Req(List<BusMaterialSrmSub> busMaterialSrmSub) {
        List<Long> srmSubIds = Lists.newArrayList();
        Map<Long, BigDecimal> srmSubOrderQtyMap = Maps.newHashMap();
        Map<Long, List<BusMaterialSrmSub>> contractMap = Maps.newHashMap();
        busMaterialSrmSub.stream().forEach(busSub -> {
            srmSubIds.add(busSub.getBusMaterialSrmSubId());
            srmSubOrderQtyMap.put(busSub.getContractsmatdtlId(), busSub.getOrderThisTimeQty());
        });

        srmSubService.listByIds(srmSubIds).stream().forEach(busSub1 -> {
            busSub1.setOrderThisTimeQty(srmSubOrderQtyMap.get(busSub1.getContractsmatdtlId()));
            if (contractMap.containsKey(busSub1.getContractsId())) {
                contractMap.get(busSub1.getContractsId()).add(busSub1);
            } else {
                List<BusMaterialSrmSub> busMaterialSrmSubs = Lists.newArrayList();
                busMaterialSrmSubs.add(busSub1);
                contractMap.put(busSub1.getContractsId(), busMaterialSrmSubs);
            }
        });

        List<SrmPms02Req> srmPms02Reqs = Lists.newArrayList();
        contractMap.forEach((contractId, srmSubs) -> {
            SrmPms02Req srmPms02Req = new SrmPms02Req();
            srmPms02Req.setContractsId(contractId);
            List<SrmPms02ReqDetail> detailsReq = Lists.newArrayList();
            srmSubs.stream().forEach(srmSubOut -> {
                SrmPms02ReqDetail srmPms02ReqDetail = new SrmPms02ReqDetail();
                // 合同明细ID
                srmPms02ReqDetail.setContractsMatDtlId(srmSubOut.getContractsmatdtlId());
                // 本次下单量
                srmPms02ReqDetail.setPurchaseNum(srmSubOut.getOrderThisTimeQty());
                detailsReq.add(srmPms02ReqDetail);
            });
            srmPms02Req.setDetails(detailsReq);
            srmPms02Reqs.add(srmPms02Req);
        });
        return srmPms02Reqs;
    }

    /**
     * 更新SRM关联子表
     */
    public void saveOrUpdateBusMaterialSrmSub(List<BusMaterialSrmSub> busMaterialSrmSub) {
        List<BusMaterialSrmSub> updSubList = Lists.newArrayList();
        busMaterialSrmSub.stream().forEach(busSub -> {
            BusMaterialSrmSub busMaterialSrmSubFromDB = srmSubService.getById(busSub.getBusMaterialSrmSubId());
            busMaterialSrmSubFromDB.setOrderFlg(ApiConstants.ORDER_FLG_ON);
            busMaterialSrmSubFromDB.setOrderThisTimeQty(busSub.getOrderThisTimeQty());
            updSubList.add(busMaterialSrmSubFromDB);
        });
        srmSubService.updateBatchById(updSubList);
    }

//    /**
//     * 组装SRM03请求数据
//     */
//    public List<SrmPms03Req> getSrmPms03Req(Object busMaterialPlans, BusProjectSupplier busSuppliers, int ver, String userName) throws InvocationTargetException, IllegalAccessException {
//        List<SrmPms03Req> reqs = Lists.newArrayList();
//        SrmProjectinfo projectInfo = pmsApiUtil.getProjectInfoFromSrm(busSuppliers.getProjectId());
//        if (ApiConstants.VER_100 == ver) {
//            List<BusMaterialPackage100> package100s = (List<BusMaterialPackage100>) busMaterialPlans;
//            for (int i = 1; i < 11; i++) {
//                Method getSupplierId = ReflectUtil.getMethod(BusProjectSupplier.class, ApiConstants.INVOKE_GET_SUPPLIERID + i);
//                Object supplierIdO = getSupplierId.invoke(busSuppliers);
//                Long supplierIdL = 0L;
//                if (null != supplierIdO) {
//                    SrmPms03Req srmPms03Req = new SrmPms03Req();
//                    supplierIdL = (Long) supplierIdO;
//                    Method getSupplierNum = ReflectUtil.getMethod(BusMaterialPackage100.class, "getSupplierNum" + i);
//
//                    BusMaterialPackage100 hearder = package100s.stream().findFirst().get();
//                    Map<String, Object> searchMap = Maps.newHashMap();
//                    searchMap.put("projectId", hearder.getProjectId());
//                    searchMap.put("majorCode", hearder.getMajorCode());
//                    searchMap.put("packageNo", hearder.getPackageNo());
//                    searchMap.put("supplierCode", srmVendorService.getById(supplierIdL).getVendorCode());
//                    List<BusPackageSrm> searchSrmRs = (List<BusPackageSrm>) busPackageSrmService.listByMap(searchMap);
//                    srmPms03Req.setContractsId(searchSrmRs.stream().findFirst().get().getContractsId());
//                    // 变更类型
//                    srmPms03Req.setChangeType("分承包合同变更");
//                    // 申请人名称
//                    srmPms03Req.setCreateUserName(userName);
//                    // 申请日期
//                    srmPms03Req.setCreateTime(System.currentTimeMillis());
//
//                    List<SrmPms03ReqDetail> detailReq = Lists.newArrayList();
//                    package100s.stream().forEach(packageObj -> {
//                        try {
//                            Object supplierNumContractO = getSupplierNum.invoke(busSuppliers);
//                            BigDecimal supplierNumContractL = BigDecimal.ZERO;
//                            if (null != supplierNumContractO) {
//                                supplierNumContractL = (BigDecimal) supplierNumContractO;
//                                SrmPms03ReqDetail srmPms03ReqDetail = new SrmPms03ReqDetail();
//                                srmPms03ReqDetail.setWbsNo(packageObj.getServiceWbsCode());
//                                srmPms03ReqDetail.setMaterialCode(packageObj.getServiceCode());
//                                srmPms03ReqDetail.setChangeQty(supplierNumContractL);
//                                detailReq.add(srmPms03ReqDetail);
//                            }
//                        } catch (IllegalAccessException e) {
//                            e.printStackTrace();
//                        } catch (InvocationTargetException e) {
//                            e.printStackTrace();
//                        }
//                    });
//                    srmPms03Req.setDetail(detailReq);
//                    reqs.add(srmPms03Req);
//                }
//            }
//        } else {
//            // TODO:200
//        }
//
//        return reqs;
//    }

    /**
     * 分包计划产值录入-SRM04
     * 【分承包】对内验工月报的产值填入
     * PMS在生成完验工月包后，会以合同为单位发起送收货请求。该请求异步请求，PMS不需要同步等待SRM的回调通知。
     * SRM收到该请求后，自动生成送货单。后又财务分承包业务，进行点收审核。
     */
    public SrmPms04Req getSrmPms04Req(List<BusReport> busReportsIn, int ver) throws Exception {
        BusReport header = busReportsIn.get(0);
        BusMaterialSrmSub busMaterialSrmSubHeader = pmsApiUtil.getBusMaterialSrmSubForPackageForPms04(header.getMaterialId(), header.getSupplierId(), ver, header.getPackageNo());
        if (null == busMaterialSrmSubHeader || null == busMaterialSrmSubHeader.getMaterialPackageId()) {
            throw new Exception("分包计划产值录入-SRM04---SRM关联合同数据丢失");
        }
        SrmPms04Req srmPms04Req = new SrmPms04Req();
        // 采购订单ID
        srmPms04Req.setPurchaseOrderId(busMaterialSrmSubHeader.getPurchaseorderId());

        List<SrmPms04ReqDetail> srmPms04ReqDetails = Lists.newArrayList();
        busReportsIn.stream().forEach(busReport -> {
            BusMaterialSrmSub busMaterialSrmSub = pmsApiUtil.getBusMaterialSrmSubForPackageForPms04(busReport.getMaterialId(), busReport.getSupplierId(), ver, header.getPackageNo());
            SrmPms04ReqDetail srmPms04ReqDetail = new SrmPms04ReqDetail();
            // 采购订单明细ID
            srmPms04ReqDetail.setPurchaseOrderDetailId(busMaterialSrmSub.getPurchaseorderDetailid());
            // 点收数量
            srmPms04ReqDetail.setAcceptQty(NumberUtil.mul(busReport.getConfirmQuantity(), busMaterialSrmSubHeader.getPmsPrice()));
            //验工月报记录ID
            srmPms04ReqDetail.setReportId(busReport.getReportId());
            srmPms04ReqDetails.add(srmPms04ReqDetail);
        });
        srmPms04Req.setDetails(srmPms04ReqDetails);
        return srmPms04Req;
    }

    /**
     * 组装SRM05请求数据
     *
     * @param projectId 项目ID
     * @param majorCode 专业编码
     * @param packageNo 工程包代码
     * @param ver       版本
     * @param userName  用户名
     * @return
     */
    public List<SrmPms05Req> getSrmPms05Req(Long projectId, String majorCode, String packageNo, int ver, String userName) throws Exception {
        List<Object> packageDataList = pmsApiUtil.getMaterialPackageDataObjList(projectId, majorCode, packageNo, 0L);

        // 判断当前计划中是否存在，临时版本，存在则停止合同下达
        if (packageDataList.stream().anyMatch(packageObj -> PmsToolUtil.getIntValue(packageObj, ApiConstants.INVOKE_GET_VERSIONSTATUS) == ApiConstants.VERSION_STATUS_ON)) {
            throw new Exception(ApiConstants.ERR_MSG_SRM05_02);
        }

        // 项目&专业&工程包&供应商关系对象
        BusProjectSupplier busProjectSupplier = pmsApiUtil.getBusProjectSupplier(projectId, majorCode, packageNo);
        if (null == busProjectSupplier.getProjectId()) {
            throw new Exception(ApiConstants.ERR_MSG_SRM05_01);
        }

        BusProjectPackSyncSrm busProjectPackSyncSrm = pmsApiUtil.getBusProjectPackSyncSrm(projectId, majorCode, packageNo);
        BusProject projectInfo = pmsApiUtil.getProjectInfo(projectId);
        List<SrmPms05Req> reqs = Lists.newArrayList();
        for (int i = 1; i < ApiConstants.INT_ELEVEN; i++) {

            // 判断如果非初次【SRM合同下达】时，判断该次循环供应商是否需要再次同步
            if (null != busProjectPackSyncSrm) {
                Long supplierIdForSync = PmsToolUtil.getLongValue(busProjectPackSyncSrm, ApiConstants.INVOKE_GET_SUPPLIERID + i);
                String syncStatus = PmsToolUtil.getStrValue(busProjectPackSyncSrm, ApiConstants.INVOKE_GET_SYNCSTATUS + i);
                if (null != supplierIdForSync && !ApiConstants.PACKAGE_SRM_SYNC_FAIL.equals(syncStatus)) {
                    // 同步状态为0 正在同步 1 同步成功 的，不作为SRM同步对象
                    if (ApiConstants.PACKAGE_SRM_SYNC_ING.equals(syncStatus)
                        || ApiConstants.PACKAGE_SRM_SYNC_SUCESS.equals(syncStatus)) {
                        StaticLog.debug("同步状态为0 正在同步 1 同步成功 的，不作为SRM同步对象----syncStatus : " + syncStatus);
                        continue;
                    }
                }
            }

            Long supplierId = PmsToolUtil.getLongValue(busProjectSupplier, ApiConstants.INVOKE_GET_SUPPLIERID + i);
            StaticLog.info("busProjectSupplier-getsupplierId:" + i + "-------" + supplierId);
            if (0L != supplierId) {
                BusSupplier busSupplier = pmsApiUtil.getBusSupplier(supplierId, null);
                SrmPms05Req srmPms05Req = new SrmPms05Req();
                // 项目编码
                srmPms05Req.setProjectNo(projectInfo.getProjectCode());
                // 项目名称
                srmPms05Req.setProjectName(projectInfo.getProjectName());
                // 专业包代码
                srmPms05Req.setMajorCode(majorCode);
                // 专业包名称
                srmPms05Req.setMajorName(majorCode);
                // 工程包代码
                srmPms05Req.setPackageNo(packageNo);
                // 工程包名称
                srmPms05Req.setPackageName(packageNo);
                // 供应商编码
                srmPms05Req.setVendorNo(busSupplier.getSupplierCode());
                // 公司编码
                srmPms05Req.setCompanyCode(ApiConstants.COMPANY_CODE);
                // 公司名称
                srmPms05Req.setCompanyName(ApiConstants.COMPANY_NM);
                // 采购组编码
                srmPms05Req.setPurchasingGroupCode(projectInfo.getBusinessPurGroupCode());
                // 采购组名称
                srmPms05Req.setPurchasingGroupName(projectInfo.getBusinessPurGroupName());
                // 申请人名称
                srmPms05Req.setProposer(userName);

                int index = i;
                List<SrmPms05ReqDetail> detailReq = Lists.newArrayList();
                packageDataList.stream().forEach(paObj -> {
                    BigDecimal supplierNum = PmsToolUtil.getBigDecimalValue(paObj, ApiConstants.INVOKE_GET_SUPPLIERNUM + index);
                    BusMaterial busMaterial = busMaterialService.getById(PmsToolUtil.getLongValue(paObj, ApiConstants.INVOKE_GET_MATERIALID));
                    if (null != supplierNum && BigDecimal.ZERO.compareTo(supplierNum) < 0) {
                        SrmPms05ReqDetail srmPms05ReqDetail = new SrmPms05ReqDetail();
                        srmPms05ReqDetail.setVer(ver);
                        srmPms05ReqDetail.setMaterialPackageIds(PmsToolUtil.getLongValue(paObj, ApiConstants.INVOKE_GET_MATERIALPACKAGE100ID));
                        srmPms05ReqDetail.setWbsNo(PmsToolUtil.getStrValue(paObj, ApiConstants.INVOKE_GET_SERVICEWBSCODE));
                        srmPms05ReqDetail.setMaterialName(PmsToolUtil.getStrValue(paObj, ApiConstants.INVOKE_GET_SERVICECODE));
                        SrmService srmService = pmsApiUtil.getSrmService(PmsToolUtil.getStrValue(paObj, ApiConstants.INVOKE_GET_SERVICECODE));
                        if(null != srmService) {
                            // 技术参数
//                            srmPms05ReqDetail.setTechnicalParameter(srmService.getServiceName());
                            srmPms05ReqDetail.setMaterialName(PmsToolUtil.getStrValue(paObj, ApiConstants.INVOKE_GET_SERVICECODE) + " " + srmService.getServiceName());
                        }
                        srmPms05ReqDetail.setPlantCode(ApiConstants.COMPANY_CODE);
                        // 预算成本单价_未税_主材价 * 数量
                        // srmPms05ReqDetail.setQty(NumberUtil.mul(supplierNum, busMaterial.getInstallPrice()));
                        srmPms05ReqDetail.setQty(BigDecimal.ZERO);
                        srmPms05ReqDetail.setPmsCount(supplierNum);
                        srmPms05ReqDetail.setPackageDesc(PmsToolUtil.getStrValue(paObj, ApiConstants.INVOKE_GET_PACKAGEDESC));
                        srmPms05ReqDetail.setUnitCode("SHI");
                        srmPms05ReqDetail.setUnitName(busMaterial.getMeasurementUnit());
                        detailReq.add(srmPms05ReqDetail);
                    }
                });

                if (0 != detailReq.size()) {
                    srmPms05Req.setDetails(detailReq);
                    reqs.add(srmPms05Req);
                }
            }

            // 判断如果非初次【SRM合同下达】时，重置供应商合同同步状态
            if (null != busProjectPackSyncSrm) {
                Long supplierIdForSync = PmsToolUtil.getLongValue(busProjectPackSyncSrm, ApiConstants.INVOKE_GET_SUPPLIERID + i);
                if (null != supplierIdForSync && !supplierIdForSync.equals(0L)) {
                    PmsToolUtil.setValue(busProjectPackSyncSrm, ApiConstants.INVOKE_SET_SYNCSTATUS + i, ApiConstants.PACKAGE_SRM_SYNC_ING);
                }
            }

        }

        if (0 == reqs.size()) {
            throw new Exception("当前无合同要下达。");
        }

        // SRM合同同步处理
//        if (null != busProjectPackSyncSrm.getSyncId()) {
//            busProjectPackSyncSrm.setStatus(ApiConstants.PACKAGE_SRM_SYNC_ING);
//        }

        if (null == busProjectPackSyncSrm) {
            busProjectPackSyncSrm = new BusProjectPackSyncSrm();
            busProjectPackSyncSrm.setProjectId(projectId);
            busProjectPackSyncSrm.setMajorCode(majorCode);
            busProjectPackSyncSrm.setPackageNo(packageNo);
            for (int i = 1; i < ApiConstants.INT_ELEVEN; i++) {
                Long supplierId = PmsToolUtil.getLongValue(busProjectSupplier, ApiConstants.INVOKE_GET_SUPPLIERID + i);
                if (0L != supplierId) {
                    PmsToolUtil.setValue(busProjectPackSyncSrm, ApiConstants.INVOKE_SET_SUPPLIERID + i, supplierId);
                    PmsToolUtil.setValue(busProjectPackSyncSrm, ApiConstants.INVOKE_SET_SYNCSTATUS + i, ApiConstants.PACKAGE_SRM_SYNC_ING);
                }
            }
            syncPackSrmService.save(busProjectPackSyncSrm);
        } else {
            BusProjectPackSyncSrm finalBusProjectPackSyncSrm = busProjectPackSyncSrm;
            List<Long> vendors = Lists.newArrayList();
            reqs.stream().forEach(reqObj -> {
                BusSupplier busSupplier = pmsApiUtil.getBusSupplier(null, reqObj.getVendorNo());
                vendors.add(busSupplier.getSupplierId());
            });
            for (int i = 1; i < ApiConstants.INT_ELEVEN; i++) {
                Long supplierId = PmsToolUtil.getLongValue(busProjectSupplier, ApiConstants.INVOKE_GET_SUPPLIERID + i);
//                if(null == supplierId || 0L == supplierId) {
//                    PmsToolUtil.setValue(busProjectPackSyncSrm, ApiConstants.INVOKE_SET_SYNCSTATUS + i, null);
//                }
                if (0L != supplierId && vendors.contains(supplierId)) {
                    PmsToolUtil.setValue(busProjectPackSyncSrm, ApiConstants.INVOKE_SET_SUPPLIERID + i, supplierId);
                    PmsToolUtil.setValue(busProjectPackSyncSrm, ApiConstants.INVOKE_SET_SYNCSTATUS + i, ApiConstants.PACKAGE_SRM_SYNC_ING);
                }
            }
            syncPackSrmService.updateById(busProjectPackSyncSrm);
        }

        // 锁定分包计划数据
        StaticLog.info("锁定分包数据1---start");
        List<Object> packageDataObjListForLock = pmsApiUtil.getMaterialPackageDataObjListForLock(projectId, majorCode, packageNo);
        packageDataObjListForLock.stream().forEach(obj -> {
            PmsToolUtil.setValue(obj, ApiConstants.INVOKE_SET_SRMSYNCSTATUS, ApiConstants.PACKAGE_CONTRACT_ON);
        });
        StaticLog.info("锁定分包数据1---end");
        pmsApiUtil.updatePlanPackageData(packageDataObjListForLock, ApiConstants.INT_ONE, ver);

        return reqs;
    }

    private Map<Long, SrmVendor> getSrmVendorInfos(BusPurchase busPurchase) {
        Map<Long, Long> vendorIdMap = Maps.newHashMap();
        busPurchase.getDetails().stream().forEach(detailObj -> {
            vendorIdMap.put(detailObj.getVendorId(), detailObj.getVendorId());
        });

        Map<Long, SrmVendor> vendorMap = Maps.newHashMap();
        vendorIdMap.forEach((id, val) -> {
            SrmVendor vendor = srmVendorService.getById(id);
            if (null == vendor) {
                vendorMap.put(id, new SrmVendor());
            } else {
                vendorMap.put(id, vendor);
            }
        });
        return vendorMap;
    }

    /**
     * 更新SRM合同下达对应的分包计划的合同同步状态
     */
    public void closeSrmSyncForPackage(Long projectId, String majorCode, String packageNo, List<String> errList) {
        if (0 < errList.size()) {
            return;
        }
        BusProjectPackSyncSrm busProjectPackSyncSrm = pmsApiUtil.getBusProjectPackSyncSrm(projectId, majorCode, packageNo);
        busProjectPackSyncSrm.setStatus(ApiConstants.PACKAGE_SRM_SYNC_FAIL);
        errList.stream().forEach(supplierCode -> {
            BusSupplier busSupplier = busSupplierService.getByProperty("supplierCode", supplierCode);
            for (int i = 1; i < ApiConstants.INT_ELEVEN; i++) {
                Object supplierIdForSync = PmsToolUtil.getValue(busProjectPackSyncSrm, ApiConstants.INVOKE_GET_SUPPLIERID + i);
                if (null != supplierIdForSync) {
                    Long vendorId = Long.valueOf(String.valueOf(supplierIdForSync));
                    if (vendorId.equals(busSupplier.getSupplierId())) {
                        PmsToolUtil.setValue(busProjectPackSyncSrm, ApiConstants.INVOKE_SET_SYNCSTATUS + i, ApiConstants.PACKAGE_SRM_SYNC_FAIL);
                    }
                }
            }
        });

    }

    /**
     * 组装SRM03请求数据
     */
    public List<SrmPms03Req> getSrmPms03Req(Long projectId, String majorCode, String packageNo, Integer ver, String userName) {
        // 专业工程包的供应商绑定数据
        BusProjectSupplier busProjectSupplier = pmsApiUtil.getBusProjectSupplier(projectId, majorCode, packageNo);
        // SRM关联子表数据
        Collection<BusMaterialSrmSub> busMaterialSrmSubList = pmsApiUtil.getBusMaterialSrmSubForPackageForSrm03(projectId, majorCode, packageNo, ver);
        if (0 == busMaterialSrmSubList.size()) {
            StaticLog.debug("-----分包计划变更-SRM03---getSrmPms03Req-无合同数据，应优先下达SRM合同。");
            StaticLog.debug("-----分包计划变更-SRM03---getSrmPms03Req-projectI：" + projectId);
            StaticLog.debug("-----分包计划变更-SRM03---getSrmPms03Req-majorCode" + majorCode);
            StaticLog.debug("-----分包计划变更-SRM03---getSrmPms03Req-packageNo" + packageNo);
            StaticLog.debug("-----分包计划变更-SRM03---getSrmPms03Req-ver" + ver);
            return Lists.newArrayList();
        }
        // PMS发起合同变更
        // 场景1：计划中存在，而SRM关联表不存在：明细行为添加行
        //       根据供应商的合同量，发送合同变更请求
        // 场景2：计划中存在，SRM关联表存在,但是供应商是新添加的。
        //       根据新供应商，发送合同变更请求
        // 场景3：计划中存在，而SRM关联表存在,供应商一致，但是数量不一致
        //      根据发生变化的合同量，供应商，发送合同变更请求

        // 抽取计划数据中，没有合同发起锁定固定的行数据，
        // 条件1：去除负数行
        //

        Map<Long, List<Object>> sendKind2Or3Map = Maps.newHashMap();
        List<Object> packageData = pmsApiUtil.getMaterialPackageDataObjList(projectId, majorCode, packageNo, 0L);

        // 获取变更供应商
        List<Long> vendorReqs = pmsApiUtil.getChangedPackageDataOfSupplier(packageData, busMaterialSrmSubList, ver);

        packageData.stream().forEach(paobj -> {
//            Long materialPackage100Id = PmsToolUtil.getLongValue(paobj, ApiConstants.INVOKE_GET_MATERIALPACKAGE100ID);
//            Long packagePlan100Id = PmsToolUtil.getLongValue(paobj, "getPackagePlan100Id");
            Long compareId = getRelationId(paobj, ver);
//            StaticLog.info("getSrmPms03Req---materialPackage100Id---:" + materialPackage100Id);
//            StaticLog.info("getSrmPms03Req---packagePlan100Id---:" + packagePlan100Id);
            StaticLog.info("getSrmPms03Req---compareId---:" + compareId);
            List<BusMaterialSrmSub> filterData = busMaterialSrmSubList.stream().filter
                (pkF -> pkF.getMaterialPackageId().equals(compareId)).collect(Collectors.toList());
            StaticLog.info("getSrmPms03Req---filterData---:" + filterData);
            BusProjectPackSyncSrm busProjectPackSyncSrm = pmsApiUtil.getBusProjectPackSyncSrm(projectId, majorCode, packageNo);

            for (int i = 1; i < ApiConstants.INT_ELEVEN; i++) {
                Long vendorId = PmsToolUtil.getLongValue(busProjectSupplier, ApiConstants.INVOKE_GET_SUPPLIERID + i);
                if (vendorReqs.contains(vendorId)) {
                    BigDecimal supplierNum = PmsToolUtil.getBigDecimalValue(paobj, ApiConstants.INVOKE_GET_SUPPLIERNUM + i);
                    Long supperIdSync = PmsToolUtil.getLongValue(busProjectPackSyncSrm, ApiConstants.INVOKE_GET_SUPPLIERID + i);
                    if (null != supperIdSync && supperIdSync.equals(vendorId)) {
                        String syncStatus = PmsToolUtil.getStrValue(busProjectPackSyncSrm, ApiConstants.INVOKE_GET_SYNCSTATUS + i);
                        if (!ApiConstants.SYNCSTATUS_FOR_CONTRACT_SYNC_OK.equals(syncStatus)) {
                            StaticLog.info("vendorId：" + vendorId + "的SRM合同未同步成功或合同同步失败");
                            continue;
                        }
                    }
                    if (null != vendorId & 0L != vendorId && null != supplierNum && !BigDecimal.ZERO.equals(supplierNum)) {
                        StaticLog.debug("vendorId：" + vendorId);
                        StaticLog.debug("supplierNum：" + supplierNum);
                        // 场景1：计划中存在，而SRM关联表不存在：明细行为添加行
                        //       根据供应商的合同量，发送合同变更请求
                        if (0 == filterData.size()) {
                            set2Or3Map(sendKind2Or3Map, vendorId, paobj);
                            StaticLog.debug("getSrmPms03Req-场景1");
                        } else {
                            Collection<BusMaterialSrmSub> subsCheckList = filterData.stream().filter(
                                fl -> fl.getSupplierId().equals(vendorId)
                                    && fl.getMaterialPackageId().equals(compareId)
                            ).collect(Collectors.toList());

                            if (0 == subsCheckList.size()) {
                                // 场景2：计划中存在，SRM关联表存在,但是供应商是新添加的。
                                // 有计划明细ID,供应商是新添加的
                                set2Or3Map(sendKind2Or3Map, vendorId, paobj);
                                StaticLog.debug("getSrmPms03Req-场景2");
                            } else {
                                // 场景3：计划中存在，而SRM关联表存在,供应商一致，但是数量不一致
                                //       根据发生变化的合同量，供应商，发送合同变更请求
                                //       只要追加的数据，追减的数据，又SRM手动自己变更，PMS制作记录。
//                            BusMaterialSrmSub busMaterialSrmSub = subsCheckList.stream().findFirst().get();
//                            BigDecimal qtyPackVal = PmsToolUtil.getBigDecimalValue(paobj, ApiConstants.INVOKE_GET_SUPPLIERNUM + i);
//                            if (busMaterialSrmSub.getPmsCount().compareTo(qtyPackVal) != 0) {
                                set2Or3Map(sendKind2Or3Map, vendorId, paobj);
                                StaticLog.debug("getSrmPms03Req-场景3");
//                            }
                            }
                        }
                    }
                }
            }
        });

        if (0 == sendKind2Or3Map.size()) {
            StaticLog.debug("-----分包计划变更-SRM03---sendKind2Or3Map.size()-未发现变更合同的数据。");
            return null;
        }

        List<SrmPms03Req> srmPms03ReqList = Lists.newArrayList();
        sendKind2Or3Map.forEach((vendorId, packageDatas) -> {
            SrmPms03Req srmPms03Req = new SrmPms03Req();
            // 变更类型
            srmPms03Req.setChangeType("F001");
            // 申请人名称
            srmPms03Req.setCreateUserName(userName);
            // 申请日期
            srmPms03Req.setCreateTime(System.currentTimeMillis());

            BusMaterialSrmSub busMaterialSrmSubHeader = pmsApiUtil.getBusMaterialSrmSubForPackage(PmsToolUtil.getLongValue(packageDatas.get(0), ApiConstants.INVOKE_GET_MATERIALID), vendorId, ver, packageNo);
            srmPms03Req.setContractsId(busMaterialSrmSubHeader.getContractsId());
            List<SrmPms03ReqDetail> detailReq = Lists.newArrayList();
            packageDatas.stream().forEach(pkObj -> {
                BusMaterial busMaterial = busMaterialService.getById(PmsToolUtil.getLongValue(pkObj, ApiConstants.INVOKE_GET_MATERIALID));
                BusMaterialSrmSub busMaterialSrmSub = pmsApiUtil.getBusMaterialSrmSubForPackage(PmsToolUtil.getLongValue(pkObj, ApiConstants.INVOKE_GET_MATERIALID), vendorId, ver, packageNo);

                for (int i = 1; i < ApiConstants.INT_ELEVEN; i++) {
                    Long vendorIdFind = PmsToolUtil.getLongValue(busProjectSupplier, ApiConstants.INVOKE_GET_SUPPLIERID + i);
                    if (null != vendorIdFind & 0L != vendorIdFind) {
                        if (vendorIdFind.equals(vendorId)) {
                            SrmPms03ReqDetail srmPms03ReqDetail = new SrmPms03ReqDetail();
                            // 匹配合同明细ID,用分包计划ID
                            if (busMaterialSrmSub.getMaterialPackageId().equals(PmsToolUtil.getLongValue(pkObj, ApiConstants.INVOKE_GET_MATERIALPACKAGE100ID))) {
                                srmPms03ReqDetail.setContractsMatDtlId(busMaterialSrmSub.getContractsmatdtlId());
                            } else {
                                srmPms03ReqDetail.setContractsMatDtlId(0L);
                            }

                            srmPms03ReqDetail.setVer(ver);
                            srmPms03ReqDetail.setMaterialPackageIds(PmsToolUtil.getLongValue(pkObj, ApiConstants.INVOKE_GET_MATERIALPACKAGE100ID));
                            srmPms03ReqDetail.setWbsNo(PmsToolUtil.getStrValue(pkObj, ApiConstants.INVOKE_GET_SERVICEWBSCODE));
                            srmPms03ReqDetail.setMaterialName(PmsToolUtil.getStrValue(pkObj, ApiConstants.INVOKE_GET_SERVICECODE) + " " + pmsApiUtil.getSrmService(PmsToolUtil.getStrValue(pkObj, ApiConstants.INVOKE_GET_SERVICECODE)));
                            BigDecimal qtyPackVal = PmsToolUtil.getBigDecimalValue(pkObj, ApiConstants.INVOKE_GET_SUPPLIERNUM + i);

                            // 预算成本单价_未税_主材价 * 数量
                            //srmPms03ReqDetail.setChangeQty(NumberUtil.mul(qtyPackVal,busMaterial.getInstallPrice()));
                            srmPms03ReqDetail.setChangeQty(BigDecimal.ZERO);
                            srmPms03ReqDetail.setPmsCount(qtyPackVal);
                            detailReq.add(srmPms03ReqDetail);
                        }
                    }
                }
            });
            srmPms03Req.setDetails(detailReq);
//            System.out.println(JSONUtil.toJsonStr(srmPms03Req));
            srmPms03ReqList.add(srmPms03Req);
        });

        // 锁定分包计划数据
        List<Object> packageDataForLock = pmsApiUtil.getMaterialPackageDataObjListForLock(projectId, majorCode, packageNo);
        StaticLog.info("锁定分包数据2---start");
        packageDataForLock.stream().forEach(obj -> {
            PmsToolUtil.setValue(obj, ApiConstants.INVOKE_SET_SRMSYNCSTATUS, ApiConstants.PACKAGE_CONTRACT_ON);
        });
        StaticLog.info("锁定分包数据2---end");
        pmsApiUtil.updatePlanPackageData(packageDataForLock, ApiConstants.INT_ONE, ver);

        return srmPms03ReqList;
    }

    public Long getRelationId(Object paobj, Integer ver) {
        if(ApiConstants.VER_100 == ver) {
            return PmsToolUtil.getLongValue(paobj, ApiConstants.INVOKE_GET_MATERIALPACKAGE100ID);
        }
        return PmsToolUtil.getLongValue(paobj, ApiConstants.INVOKE_GET_PackagePlan100Id);
    }

    private void set2Or3Map(Map<Long, List<Object>> sendKind2Or3Map, Long vendorId, Object paobj) {
        if (sendKind2Or3Map.containsKey(vendorId)) {
            sendKind2Or3Map.get(vendorId).add(paobj);
        } else {
            List<Object> addUpd100s = Lists.newArrayList();
            addUpd100s.add(paobj);
            sendKind2Or3Map.put(vendorId, addUpd100s);
        }
    }

    /**
     * 组装同步申请清单附件到SRM请求数据
     *
     * @param purchaseId 申请记录ID
     * @return
     */
    public SrmDemandPlanSyncReq getSyncSrmFileReq(Long purchaseId) throws Exception {
        SrmDemandPlanSyncReq srmDemandPlanSyncReq = null;
        CriteriaUpdate<BusProjectFile> cu = new CriteriaUpdate();
        cu.eq("purchaseId", purchaseId);
        //查找本次申请的附件信息
        List<BusProjectFile> projectFiles = busProjectFileService.list(cu);
        if(!CollectionUtils.isEmpty(projectFiles)) {
            srmDemandPlanSyncReq = new SrmDemandPlanSyncReq();
            //申请记录ID
            srmDemandPlanSyncReq.setPurchaseId(purchaseId.toString());
            //附件明细
            List<SrmDemandPlanSyncReqDetail> details = Lists.newArrayList();
            String base64String = null;
            for(BusProjectFile file: projectFiles) {
                SrmDemandPlanSyncReqDetail detail = new SrmDemandPlanSyncReqDetail();
                detail.setProjectFileId(file.getProjectFileId());
                base64String = getFileBase64Str(file);
                if(StringUtils.isBlank(base64String)) {
                    continue;
                }
                detail.setFileStr(base64String);
                detail.setFileName(file.getFileName());
                details.add(detail);
            }
            //不存在附件
            if(CollectionUtils.isEmpty(details)) {
                return null;
            }
            srmDemandPlanSyncReq.setDetails(details);
        }
        StaticLog.debug("附件同步返回-----", JSONObject.toJSONString(srmDemandPlanSyncReq));
        return srmDemandPlanSyncReq;
    }

    /**
     * 获取文件base64
     * @param projectFile 申请记录附件明细记录
     * @return
     */
    public String getFileBase64Str(BusProjectFile projectFile) {
        String downFilePath = filePath + projectFile.getFilePath();
        String base64String = null;
        File file = new File(downFilePath);
        if(!file.exists()) {
            return base64String;
        }
        try {
            InputStream is = new FileInputStream(file);
            ByteArrayOutputStream byteos = new ByteArrayOutputStream();
            int read;
            int length = is.available();
            byte[] bytes = new byte[length];
            while ((read = is.read(bytes)) > 0) {
                byteos.write(bytes, 0, read);
            }
            base64String = Base64Utils.encodeToString(bytes);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return base64String;
    }

}
